﻿using System;
using System.Collections.Generic;
using Hanhud.Security;
using System.Data;

namespace Hanhud.Web.EAuction
{
    public class CProperty : CBizObject
    {
        #region Properties
        private string _propertyID = string.Empty;
        /// <summary>
        /// Mã bất động sản
        /// </summary>
        public string PropertyID { get { return _propertyID; } protected set { _propertyID = value; } }

        private DateTime _addedDate = DateTime.Now;
        /// <summary>
        /// Ngày bất động sản được lưu trong db
        /// </summary>
        public DateTime AddedDate { get { return _addedDate; } protected set { if (value < DateTime.Now) _addedDate = value; else throw new ArgumentOutOfRangeException("Ngày tạo không thể lớn hơn ngày hiện tại được"); } }

        private DateTime _startDate = DateTime.Now;
        /// <summary>
        /// Ngày bắt đầu đăng bất động sản
        /// </summary>
        public DateTime StartDate { get { return _startDate; } set { _startDate = value; } }

        private DateTime _expireDate = DateTime.MaxValue;
        /// <summary>
        /// Ngày kết thúc đăng bất động sản
        /// </summary>
        public DateTime ExpireDate { get { return _expireDate; } set { _expireDate = value; } }

        private EPropertyStatus _status = EPropertyStatus.Pending;
        public EPropertyStatus Status
        {
            get { return _status; }
            private set { _status = value; }
        }

        private Guid _membershipID = Guid.Empty;
        /// <summary>
        /// get/protected set Người đăng(hoặc chủ sở hữu)
        /// </summary>
        public CMembershipUser Owner { get; protected set; }

        private Guid _brokerID = Guid.Empty;
        private CMembershipUser _broker = null;
        /// <summary>
        /// Nhà môi giới được ủy quyền
        /// </summary>
        public CMembershipUser Broker {
            get
            {
                if (_broker == null && _brokerID != Guid.Empty)
                    _broker = CMembership.GetUser(string.Empty, false);
                return _broker;
            }
            set
            {
                _broker = value;
            }
        }

        private int _propertyTypeID = -1;
        /// <summary>
        /// Kiểu bất động sản
        /// </summary>
        public CPropertyType PropertyType { get; set; }

        private CLocation _location = null;
        /// <summary>
        /// Vị trí bất động sản
        /// </summary>
        public CLocation Location
        {
            get { return _location; }
            set { _location = value; }
        }

        private string _address = string.Empty;
        /// <summary>
        /// Địa chỉ
        /// </summary>
        public string Address { get { return _address; } set { _address = value; } }

        private bool _hasPoint = false;
        /// <summary>
        /// Bất động sản có được định vị hay chưa ?
        /// </summary>
        public bool HasPoint
        {
            get { return _hasPoint; }
            protected set { _hasPoint = value; }
        }

        /// <summary>
        /// Tọa độ điểm của bất động sản trên bản đồ
        /// </summary>
        public CGPoint GPoint;

        private EPropertyFor _propertyFor = EPropertyFor.ForBuy;
        /// <summary>
        /// Mục đích sử dụng
        /// </summary>
        public EPropertyFor PropertyFor { get { return _propertyFor; } set { _propertyFor = value; } }

        private string _title = string.Empty;
        /// <summary>
        /// Tên của bất động sản
        /// </summary>
        public string Title { get { return _title; } set { _title = value; } }

        private string _description = string.Empty;
        /// <summary>
        /// Thông tin mô tả ngắn gọn khác
        /// </summary>
        public string Description { get { return _description; } set { _description = value; } }

        private float _totalSize = -1;
        /// <summary>
        /// Tổng diện tích
        /// </summary>
        public float TotalSize { get { return _totalSize; } set { if (value > 0) _totalSize = value; else throw new ArgumentOutOfRangeException("Diện tích phải lớn hơn 0"); } }

        private float _totalBuildingSize = -1;
        /// <summary>
        /// Tổng diện tích xây dựng
        /// </summary>
        public float TotalBuildingSize { get { return _totalBuildingSize; } set { _totalBuildingSize = value; } }

        private int _yearBuilt = -1;
        /// <summary>
        /// Năm xây dựng
        /// </summary>
        public int YearBuilt { get { return _yearBuilt; } set { if (value <= DateTime.Now.Year && value >= 1790) _yearBuilt = value; else throw new ArgumentOutOfRangeException("Năm xây dựng phải nhỏ hơn năm hiện tại và lớn hơn 1790"); } }

        private int _numOfRoom = -1;
        /// <summary>
        /// Số phòng
        /// </summary>
        public int NumOfRoom { get { return _numOfRoom; } set { if (value > 0) _numOfRoom = value; else throw new ArgumentOutOfRangeException("Số phòng phải lớn hơn 0"); } }

        private int _numOfBedRoom = -1;
        /// <summary>
        /// Số phòng ngủ
        /// </summary>
        public int NumOfBedRoom
        {
            get { return _numOfBedRoom; }
            set
            {
                if (NumOfRoom > 0)
                {
                    if (value > 0 && value < NumOfRoom)
                        _numOfBedRoom = value;
                    else
                        throw new ArgumentOutOfRangeException("Số phòng ngủ phải lớn hơn 0 và nhỏ hơn số phòng");
                }
                else
                {
                    if (value > 0)
                        _numOfBedRoom = value;
                    else
                        throw new ArgumentOutOfRangeException("Số phòng ngủ phải lớn hơn 0");
                }
            }
        }

        private string _lotNo = string.Empty;
        /// <summary>
        /// Số lô
        /// </summary>
        public string LotNo { get { return _lotNo; } set { _lotNo = value; } }

        private string _plotNo = string.Empty;
        /// <summary>
        /// Số thửa
        /// </summary>
        public string PlotNo { get { return _plotNo; } set { _plotNo = value; } }

        private float _askingPrice = 0;
        /// <summary>
        /// Giá đề nghị
        /// </summary>
        public float AskingPrice { get { return _askingPrice; } set { if (value > 0) _askingPrice = value; else throw new ArgumentOutOfRangeException("Giá đề nghị phải lớn hơn 0"); } }

        private string _constructionStatus = string.Empty;
        /// <summary>
        /// Trạng thái xây dựng
        /// </summary>
        public string ConstructionStatus { get { return _constructionStatus; } set { _constructionStatus = value; } }

        private EDirection _direction = EDirection.Unknown;
        /// <summary>
        /// Hường nhà
        /// </summary>
        public EDirection Direction { get { return _direction; } set { _direction = value; } }

        private List<string> _highlights = new List<string>();
        /// <summary>
        /// Các thuộc tính nổi bật của bất động sản
        /// </summary>
        public List<string> Highlights
        {
            get { return _highlights; }
        }

        private int _viewCount = 0;
        /// <summary>
        /// Tổng số lần xem
        /// </summary>
        public int ViewCount { get { return _viewCount; } protected set { _viewCount = value; } }

        private int _votes = 0;
        /// <summary>
        /// Số lần Votes
        /// </summary>
        public int Votes
        {
            get { return _votes; }
            set { _votes = value; }
        }

        private int _totalRating = 0;
        /// <summary>
        /// Tổng số điểm votes
        /// </summary>
        public int TotalRating
        {
            get { return _totalRating; }
            private set { _totalRating = value; }
        }
        /// <summary>
        /// Điểm vote trung bình
        /// </summary>
        /// <value>The average rating.</value>
        public double AverageRating
        {
            get
            {
                if (this.Votes >= 1)
                    return ((double)this.TotalRating / (double)this.Votes);
                else
                    return 0D;
            }
        }

        private List<CPhoto> _photos = null;
        public List<CPhoto> PhotoCollection
        {
            get { return _photos; }
            private set { _photos = value; }
        }
        #endregion

        #region Constructors
        public CProperty(string propertyID)
        {
            this.PropertyID = propertyID;
        } 
        #endregion

        #region Public methods
        /// <summary>
        /// Cập nhật các thông tin của bất động sản
        /// </summary>
        public bool Update()
        {
            return false;
        }

        /// <summary>
        /// Xóa bất động sản
        /// </summary>
        public bool Delete()
        {
            return false;
        }

        /// <summary>
        /// Tăng số lượng view
        /// </summary>
        public void IncrementViewCount()
        {
            Data.Providers.CAuctionProvider.Instance.IncrementPropertyViewCount(this.PropertyID);
            ViewCount++;

        }

        /// <summary>
        /// Vote bất động sản
        /// </summary>
        public void Rate(int rating)
        {
            // Cap nhat so diem vote

            // Tang so lan vote len 1
            Votes++;
        }

        /// <summary>
        /// Lấy tọa độ của bất động sản
        /// </summary>
        /// <returns></returns>
        public CGPoint GetPoint()
        {
            return 
                new CGPoint();
        }
        #endregion

        /// <summary>
        /// Lấy thông tin chi tiết của 1 bất động sản
        /// </summary>
        public static CProperty GetPropertyInfo(string propertyID)
        {
            CProperty property = GetPropertyFromDataRow(Data.Providers.CAuctionProvider.Instance.GetPropertyInfo(propertyID));

            if (property != null)
            {
                DataTable tblHighlight = Data.Providers.CAuctionProvider.Instance.GetPropertyHighlights(property.PropertyID);
                foreach (DataRow row in tblHighlight.Rows)
                {
                    property.Highlights.Add(row["Title"].ToString());
                }
            }

            return property;
        }

        /// <summary>
        /// Thêm mới bất động sản
        /// </summary>
        /// <param name="owner">Chủ sở hữu(Người đăng tin)</param>
        /// <param name="broker">Nhà môi giới (Đại lý)</param>
        /// <param name="location">Vị trí của bất động sản</param>
        /// <param name="address">Địa chỉ</param>
        /// <param name="propertyType">Kiểu bất động sản(Nhà, văn phòng, đất)</param>
        /// <param name="propertyFor">Loại hình giao dịch (Mua, bán, cho thuê, chuyển nhượng)</param>
        public static CProperty AddProperty(CMembershipUser owner, CMembershipUser broker, CLocation location, string address, CPropertyType propertyType, EPropertyFor propertyFor)
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// Cập nhật lại các thông tin của bất động sản
        /// </summary>
        /// <param name="propertyID">Mã bất động sản</param>
        public static bool UpdateProperty(string propertyID)
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// Lấy danh sách bất động sản theo các điều kiện
        /// </summary>
        /// <param name="owner">Chủ sở hữu</param>
        /// <param name="broker">Nhà môi giới</param>
        /// <param name="propertyForList">Danh sách mục đích của bất động sản</param>
        /// <param name="propertyTypeList">Danh sách kiểu bất động sản</param>
        /// <param name="startDate">Bắt đầu từ ngày</param>
        /// <param name="endDate">Đến ngày</param>
        /// <param name="statusList">Danh sách trạng thái</param>
        /// <param name="keyword">Từ khóa tìm kiếm</param>
        /// <param name="exactWord">Tìm chính xác ?</param>
        /// <param name="provinceCode">Mã tỉnh/thành</param>
        /// <param name="districtCode">Mã quận/huyện</param>
        /// <param name="communeCode">Mã phường/xã</param>
        /// <param name="fromPrice">Giá từ</param>
        /// <param name="toPrice">Giá đến</param>
        /// <param name="fromSize">Diện tích từ</param>
        /// <param name="toSize">Diện tích đến</param>
        /// <param name="fromNumOfBedRoom">Số phòng ngủ từ</param>
        /// <param name="toNumOfBedRoom">Số phòng ngủ đến</param>
        /// <param name="directionList">Danh sách hướng</param>
        /// <param name="pageIndex">Chỉ số trang</param>
        /// <param name="pageSize">Số lượng kết quả / trang</param>
        /// <returns>Danh sách bất động sản đã được lọc</returns>
        public static CTypeCollection<CProperty> GetFilterProperties(
                CMembershipUser owner,              // Chủ sở hữu
                CMembershipUser broker,             // Nhà môi giới
                EPropertyFor[] propertyForList,     // Mục đích sử dụng
                CPropertyType[] propertyTypeList,   // Kiểu bất động sản
                DateTime startDate,                 // Từ ngày
                DateTime endDate,                   // Đến ngày
                EPropertyStatus[] statusList,       // Danh sách trạng thái
                string keyword,                     // Từ khóa tìm kiếm
                bool exactWord,                     // Tìm chính xác
                int provinceCode,                   // Mã tỉnh/thành
                int districtCode,                   // Mã quận/huyện
                int communeCode,                    // Mã phường/xã
                float fromPrice,                    // Giá từ
                float toPrice,                      // Giá đến
                float fromSize,                     // Diện tích từ
                float toSize,                       // Diện tích đến
                int fromNumOfBedRoom,               // Số phòng ngủ từ
                int toNumOfBedRoom,                 // Số phòng ngủ đến
                EDirection[] directionList,         // Danh sách hướng
                int pageIndex,                      // Chỉ số trang
                int pageSize                        // Số lượng kết quả / trang
            )
        {
            if (endDate.Date <= startDate.Date) endDate = DateTime.MaxValue;

            if (fromPrice < 0) fromPrice = -1f;
            if (toPrice < fromPrice) toPrice = -1f;

            if (fromSize < 0) fromSize = -1f;
            if (toSize < fromSize) toSize = -1f;

            if (fromNumOfBedRoom <= 0) fromNumOfBedRoom = -1;
            if (toNumOfBedRoom <= fromNumOfBedRoom) toNumOfBedRoom = -1;

            if (pageIndex <= 0) pageIndex = 1;
            if (pageSize <= 0) pageSize = Config.CSiteConfig.Current.DefaultPageSize;

            if (keyword.Length < 3) keyword = string.Empty;
            else if (!exactWord)
            {
                //keyword = keyword;
            }

            return null;
        }

        /// <summary>
        /// Lấy danh sách bất động sản đã được đăng bởi người dùng
        /// </summary>
        /// <param name="owner">Chủ sở hữu</param>
        /// <param name="pageIndex">Chỉ số trang</param>
        /// <param name="pageSize">Số lượng kết quả / trang</param>
        /// <returns></returns>
        public static CTypeCollection<CProperty> GetOwnerProperties(CMembershipUser owner, int pageIndex, int pageSize)
        {
            return
                GetFilterProperties(
                    owner,
                    null,
                    new EPropertyFor[] { },
                    new CPropertyType[] { },
                    DateTime.MinValue,
                    DateTime.Now,
                    new EPropertyStatus[] { },
                    string.Empty,
                    false,
                    -1, -1, -1,
                    -1, -1,
                    -1, -1,
                    -1, -1,
                    new EDirection[] { },
                    pageIndex,
                    pageSize);
        }

        /// <summary>
        /// Lấy danh sách bất động sản đã được đăng bởi người dùng
        /// </summary>
        /// <param name="statusList">Danh sách trạng thái</param>
        /// <param name="owner">Chủ sở hữu</param>
        /// <param name="pageIndex">Chỉ số trang</param>
        /// <param name="pageSize">Số lượng kết quả / trang</param>
        /// <returns></returns>
        public static CTypeCollection<CProperty> GetOwnerProperties(CMembershipUser owner, EPropertyStatus[] statusList, int pageIndex, int pageSize)
        {
            return
                GetFilterProperties(
                    owner,
                    null,
                    new EPropertyFor[] { },
                    new CPropertyType[] { },
                    DateTime.MinValue,
                    DateTime.Now,
                    statusList,
                    string.Empty,
                    false,
                    -1, -1, -1,
                    -1, -1,
                    -1, -1,
                    -1, -1,
                    new EDirection[] { },
                    pageIndex,
                    pageSize);
        }

        /// <summary>
        /// Danh sách bất động sản được ủy nhiệm cho nhà môi giới
        /// </summary>
        /// <param name="broker">Nhà môi giới</param>
        /// <param name="startDate">Từ ngày</param>
        /// <param name="endDate">Đến ngày</param>
        /// <param name="statusList">Danh sách trạng thái</param>
        /// <param name="provinceCode">Tỉnh/Thành</param>
        /// <param name="districtCode">Quận/Huyện</param>
        /// <param name="communeCode">Phường/Xã</param>
        /// <param name="pageIndex">Chỉ số trang</param>
        /// <param name="pageSize">Số lượng kết quả / trang</param>
        /// <returns></returns>
        public static CTypeCollection<CProperty> GetBrokerProperties(CMembershipUser broker, DateTime startDate, DateTime endDate, EPropertyStatus[] statusList, int provinceCode, int districtCode, int communeCode, int pageIndex, int pageSize)
        {
            return
                GetFilterProperties(
                    null,
                    broker,
                    new EPropertyFor[] { },
                    new CPropertyType[] { },
                    startDate,
                    endDate,
                    statusList,
                    string.Empty,
                    false,
                    provinceCode, districtCode, communeCode,
                    -1, -1,
                    -1, -1,
                    -1, -1,
                    new EDirection[] { },
                    pageIndex,
                    pageSize);
        }

        /// <summary>
        /// Tìm kiếm đơn giản
        /// </summary>
        /// <param name="keyword">Từ khóa tìm kiếm</param>
        /// <param name="provinceCode">Tỉnh/Thành</param>
        /// <param name="districtCode">Quận/Huyện</param>
        /// <param name="communeCode">Phường/Xã</param>
        /// <param name="pageIndex">Chỉ số trang</param>
        /// <param name="pageSize">Số lượng kết quả / trang</param>
        /// <returns></returns>
        public static CTypeCollection<CProperty> GetFilterProperties(string keyword, int provinceCode, int districtCode, int communeCode, int pageIndex, int pageSize)
        {
            return
                GetFilterProperties(
                    null,
                    null,
                    new EPropertyFor[] { },
                    new CPropertyType[] { },
                    DateTime.MinValue,
                    DateTime.Now,
                    new EPropertyStatus[] { },
                    keyword,
                    false,
                    provinceCode, districtCode, communeCode,
                    -1, -1,
                    -1, -1,
                    -1, -1,
                    new EDirection[] { },
                    pageIndex,
                    pageSize);
        }

        /// <summary>
        /// Xóa bất động sản
        /// </summary>
        /// <param name="propertyID">Mã bất động sản</param>
        public static bool DeleteProperty(string propertyID)
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// Chuyển đổi từ dữ liệu trong db sang dữ liệu thuộc tính của bất động sản
        /// </summary>
        private static CProperty GetPropertyFromDataRow(DataRow row)
        {
            CProperty property = null;

            if (row != null)
            {
                property = new CProperty(row["PropertyID"].ToString());

                // Thiet lap gia tri cho cac thuoc tinh
                property.AddedDate = Convert.ToDateTime(row["AddedDate"]);
                //property.Owner
            }

            return property;
        }
    }
}
